package org.tema.web;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlInputHidden;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpSession;

import org.tema.ejb.ProductBeanLocal;
import org.tema.ejb.UserBeanLocal;
import org.tema.entities.Product;
import org.tema.entities.User;

public class ManageUsersBean {
	
	// navigation constants
	private static final String LOGOUT = "logout";
	private static final String USERS_LIST = "usersList";
	private static final String EDIT_USER = "editUser";

	@EJB
	private UserBeanLocal userBean;
	@EJB 
	private ProductBeanLocal productBean;
	private User user;
	private Product product;
	private Collection <User> userList = null;

	private User singleUser;
	// setters and getters for these prop to use them in the UserSearch
	
	private int userId;
	private int productId;
	private UserSearchTypes searchDropDown;
	private String searchWord;
	private static String groupNameAdmin= "appAdmin";
	private static String groupNameUser= "appUser";
	////user edit related variables
	private String name;
	private String password;
	private String passwordRepeat;
	private Boolean isAdmin;
	
	////end user edit related variables
	
	private HtmlDataTable dataTable;
    private HtmlInputHidden dataItemId = new HtmlInputHidden();


	public ManageUsersBean() {
		// constructor
		
	}
	
	
	//getters for the DataTable Manipulation
	
	public HtmlDataTable getDataTable() {
		return dataTable;
	}


	public void setDataTable(HtmlDataTable dataTable) {
		this.dataTable = dataTable;
	}


	public HtmlInputHidden getDataItemId() {
		return dataItemId;
	}


	public void setDataItemId(HtmlInputHidden dataItemId) {
		this.dataItemId = dataItemId;
	}


	public String logoutUser(){
		FacesContext context = FacesContext.getCurrentInstance();
		HttpSession session= (HttpSession) context.getExternalContext().getSession(false);
		if (session != null) {
		    	session.invalidate();
		}
		return LOGOUT;
	}
	
	public void validatePassword(FacesContext context, UIComponent toValidate, Object value){
		this.password = (String) value;
	}

	public void validateComparePasswords(FacesContext context, UIComponent toValidate, Object value){
		this.passwordRepeat = (String) value;
		if( ! this.password.equals(this.passwordRepeat )){
			context = FacesContext.getCurrentInstance();
			( (UIInput) toValidate ).setValid( false );
			FacesMessage message = new FacesMessage();
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			message.setSummary("Passwords don't match !");
			message.setDetail("Passwords don't match !");
			context.addMessage( toValidate.getClientId(context), message);
		}
	}
	public String deleteRegisteredUser() {
		user = (User) dataTable.getRowData();
		userBean.deleteUser(user);
		// add status message
		Status.addInfo("User " + user.getName() + " deleted. ");
		// update users list
		findAllUsers();
		return USERS_LIST;
	}
	
	public String saveRegisteredUser() {
		userBean.addUser(this.name, this.isAdmin, this.password, this.product);
		// add status message
		Status.addInfo("User " + this.name + " registered. ");
		// update users list
		findAllUsers();
		return USERS_LIST; 
	}
	
	public String displayUser() {
		User user1 = (User) dataTable.getRowData();
		user = userBean.findUserById(user1.getId());
		return EDIT_USER;
	}
	
	public String editUser() {
		userBean.updateUser(user);
		// add status message
		Status.addInfo("User " + user.getName() + " modified. ");
		// update users list
		findAllUsers();
		return USERS_LIST;
	}
	
	//end datatable manipulation
	public Collection<User> getUserList() {
		if (userList == null) {
			findAllUsers();
		}
		return userList;
	}

	
	public void setUserList(Collection<User> userList) {
		this.userList = userList;
	}

	
	public String getPassword() {
		return password;
	}


	public void setPassword(String password) {
		this.password = password;
	}
	
	public String getPasswordRepeat() {
		return passwordRepeat;
	}


	public void setPasswordRepeat(String passwordRepeat) {
		this.passwordRepeat = passwordRepeat;
	}

	
	public Boolean getIsAdmin() {
		return isAdmin;
	}


	public void setIsAdmin(Boolean isAdmin) {
		this.isAdmin = isAdmin;
	}


	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getUserId() {
		return userId;
	}

	public void setUserId(int userId) {
		this.userId = userId;
	}

	public int getProductId() {
		return productId;
	}

	public void setProductId(int productId) {
		this.productId = productId;
	}

	public User getSingleUser() {
		return singleUser;
	}

	public void setSingleUser(User singleUser) {
		this.singleUser = singleUser;
	}

	public User getUser() {
		return user;
	}


	public void setUser(User user) {
		this.user = user;
	}


	public UserSearchTypes getSearchDropDown() {
		return searchDropDown;
	}

	public void setSearchDropDown(UserSearchTypes searchDropDown) {
		this.searchDropDown = searchDropDown;
	}

	public String getSearchWord() {
		return searchWord;
	}

	public void setSearchWord(String searchWord) {
		this.searchWord = searchWord;
	}



	public Product getProduct() {
		return product;
	}


	public void setProduct(Product product) {
		this.product = product;
	}


///////////////////////////////////////////////
	public String selectSearch(){
		String result;
		switch (this.getSearchDropDown()) {
	        case UID:  		result = findById(this.getSearchWord()); break;
	        case NAME: 		result = findByUserName(this.getSearchWord()); break;
	        case UGROUP:  	result = findByGroup(this.getSearchWord()); break;
	    //    case PID:  		result = findByProductId(this.getSearchWord()); break;
	        case ALLUSERS:  result = findAllUsers(); break;
	        default: 		result = findAllUsers();
		}
		return result;
	}

	public Boolean getIsRendered() {
    	FacesContext facesContext = FacesContext.getCurrentInstance(); 
    	String userName = facesContext.getExternalContext().getRemoteUser();
    	User user = userBean.findUserByName(userName);
    	return user.getAdmin();
	}
	
	
	public String findAllUsers(){
		//String result;
		setUserList((Collection <User>) userBean.findAllUsers());
		if (getUserList().isEmpty()) {
			Status.addInfo("No users available.");
		}
		return USERS_LIST;
	}
	
	public String findById(String searchWord) {
		setUserId(Integer.parseInt(searchWord));
		try {
			setSingleUser(userBean.findUserById( this.getUserId() ));
			setUserList(Arrays.asList(singleUser));
		} catch (EJBException e) {
			Status.addError(e.getCause().getMessage());
		}
		return USERS_LIST;
	}
	
	public String findByUserName(String searchWord) {
		setName(searchWord);
		try {
			setSingleUser(userBean.findUserByName(this.getName()));
			setUserList(Arrays.asList(singleUser));
		} catch (EJBException e) {
			Status.addError(e.getCause().getMessage());
		}
		return USERS_LIST;
	}
	
	public String findByGroup( String groupName ){
		try{
			setUserList( ( Collection <User> ) userBean.findUsersInGroup(groupName) );
			
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return USERS_LIST;
	}
	
	public String findByProductId( String searchWord ){
		/*
		int id = Integer.parseInt(searchWord);
		setUserList( ( Collection <User> ) userBean.findUserByProductId( id ) );
		if ( ! getUserList().isEmpty() ){
			Status.addInfo("No users available with id: " + id );
			return USERS_LIST;
		}
		else {
			return USERS_LIST;
		}*/
		try{
			int id = Integer.parseInt(searchWord);
			setUserList( ( Collection <User> ) userBean.findUserByProductId( id ) );
			if ( ! getUserList().isEmpty() ){
				Status.addInfo("No users available with id: " + id );
			}
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return USERS_LIST;
	}
	
//start 

    // ---------------------------------------------------------- Public Methods
    
    public Collection<SelectItem> getItems() {
    	UserSearchTypes[] values = UserSearchTypes.values();
        Collection<SelectItem> list = new ArrayList<SelectItem>(values.length);
        for (UserSearchTypes value : values) {            
            list.add(new SelectItem(value, value.getLabel()));            
        }
        
        return list;
    }
    
    //create selectItems from the product names
    public Collection<SelectItem> getProductList(){
    	Collection<Product> products = productBean.findAllProducts();
    	Collection <SelectItem> productList = new ArrayList<SelectItem>( products.size() );  	
    	for( Product prod : products ){
    		productList.add( new SelectItem( prod, prod.getName() ) );
    	}
    	return productList;
    }
    
    public Converter getProductConverter() {
    	return new ProductConverter(productBean);
    }

//end

	public String printUserRole(){
		 ExternalContext facesContext = FacesContext.getCurrentInstance().getExternalContext(); 
		 System.out.println("Is the user in admin role" + facesContext.isUserInRole(groupNameAdmin) );
		 return "yes";
	}
	
	public String getLoggedUser() {
		return FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
	}
	
	
}
